﻿using System.Diagnostics;
using System.Windows;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Remote.Protocol.Input;
using Avalonia.Xaml.Interactivity;
using KinonekoSoftware.Studio.Components;
using KinonekoSoftware.UI;

namespace KinonekoSoftware.Studio.Contents
{
    public class DraggableBorder : TemplatedControl
    {
        private static readonly SolidColorBrush Transparent = new SolidColorBrush(Colors.Transparent);

        public override void Render(DrawingContext context)
        {
            base.Render(context);
            
            var rect   = new Rect(0, 0, Bounds.Width, Bounds.Height);
            var border = new SolidColorBrush(Colors.White);
            var corner = new SolidColorBrush(Colors.BlueViolet);


            //
            // 背景：透明
            // 边框: 白
            context.DrawRectangle(Transparent, new Pen(border, 2), rect);

            //
            // 边角
            //
            context.DrawEllipse(corner, null, new Point(0, -0), 8, 8);
            context.DrawEllipse(corner, null, new Point(Bounds.Width, 0), 8, 8);
            context.DrawEllipse(corner, null, new Point(0, Bounds.Height), 8, 8);
            context.DrawEllipse(corner, null, new Point(Bounds.Width, Bounds.Height), 8, 8);
        }
    }

    public class DraggableCanvasBehavior : Behavior<Canvas>
    {
        private bool                   _capture;
        private IImagePositionReceiver _imagePositionReceiver;
        
        protected override void OnAttached()
        {
            if (AssociatedObject is null)
            {
                return;
            }
            
            AssociatedObject.PointerReleased += OnMouseUp;
            AssociatedObject.PointerPressed  += OnMouseDown;
            AssociatedObject.PointerExited   += OnMouseLeave;
            AssociatedObject.Loaded          += OnLoaded;
            
            
            base.OnAttached();
        }

        protected override void OnDetaching()
        {
            if (AssociatedObject is null)
            {
                return;
            }
            
            AssociatedObject.PointerReleased -= OnMouseUp;
            AssociatedObject.PointerPressed  -= OnMouseDown;
            AssociatedObject.PointerExited      -= OnMouseLeave;
            AssociatedObject.Loaded          -= OnLoaded;
            base.OnDetaching();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (AssociatedObject is null)
            {
                return;
            }
            
            if (AssociatedObject.DataContext is IImagePositionReceiver vm)
            {
                //
                // 设置画布大小
                vm.CanvasSize          = AssociatedObject.Bounds.Size;
                _imagePositionReceiver = vm;
            }
        }


        private void OnMouseLeave(object sender, PointerEventArgs e)
        {
            if(_capture && AssociatedObject is not null)
                AssociatedObject.PointerMoved -= OnMouseMove;

            _capture = false;
            
        }
        
        private void OnMouseUp(object sender, PointerReleasedEventArgs e)
        {
            if(_capture && AssociatedObject is not null)
                AssociatedObject.PointerMoved -= OnMouseMove;

            _capture = false;
        }
        
        private void OnMouseMove(object sender, PointerEventArgs e)
        {
            if (AssociatedObject is null)
            {
                return;
            }

            
            var pos      = e.GetPosition(AssociatedObject);
            _imagePositionReceiver.SetDeltaPosition(pos.X / AssociatedObject.Bounds.Width, pos.Y / AssociatedObject.Bounds.Height);
            e.Handled = true;
        }
        
        
        private void OnMouseDown(object sender, PointerPressedEventArgs e)
        {  
            if (AssociatedObject is null)
            {
                return;
            }

            if (AssociatedObject.DataContext is not IImagePositionReceiver vm)
            {
                return;
            }

            var pos = e.GetPosition(AssociatedObject);
            vm.SetDeltaPosition(pos.X / AssociatedObject.Bounds.Width, pos.Y / AssociatedObject.Bounds.Height);
            e.Handled                     =  true;
            _capture                      =  true;
            AssociatedObject.PointerMoved += OnMouseMove;
        }
    }

    [Associate(View = typeof(ImageEditorView), ViewModel = typeof(ImageEditorViewModel))]
    public partial class ImageEditorView : ForestDialog
    {
        public ImageEditorView()
        {
            InitializeComponent();
        }
    }
}